﻿#pragma once

#include "Framework/Application.h"
#include "Widgets/Window.h"
#include "Widgets/TextWidget.h"
#include "Widgets/EditableTextWidget.h"
#include "Widgets/WindowManager.h"
#include "Widgets/CollapsibleWidget.h"
#include "Platform/PlatformInterface.h"
//#include "Widgets/Editor/EditorMenuWindow.h"

#include "Widgets/Dock/DockWidgetSubsystem.h"
#include "Widgets/Dock/DockWidgetTitleBar.h"
#include "Widgets/Dock/DockLayout.h"

#include "Widgets/CanvasWidget.h"

#include "Widgets/Windows/ContextMenuWindow.h"

#include "Asset/EngineDefaultPackage.h"

#include "Widgets/Windows/FileBrowserWidget.h"

#include "Widgets/Positioners/VerticalPositionerWidget.h"
#include "Widgets/Positioners/HorizontalPositionerWidget.h"

#include "Path/Paths.h"

#include "Widgets/Windows/FileDialog.h"

#include "Output/Console.h"

#include "Scene/Scene.h"
#include "Scene/DirectionalLightComponent.h"
#include "Scene/CameraComponent.h"
#include "Scene/InputComponent.h"
#include "Scene/StaticMeshComponent.h"
#include "Scene/TickComponent.h"
#include "Framework/SceneManager.h"

#include "Widgets/ButtonWidget.h"
#include "Widgets/WidgetAnimation.h"
#include "Widgets/ViewportWidget.h"
#include "Widgets/Windows/MessageBox.h"

#include "PixelObject/PixelObjectMap.h"


void TestMousePosition()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->MoveToScreenCenter();

  Window->StartCaptureMouse();

  auto TextWidget=NewWidget<RTextWidget>(Window->GetRootWidget());
  TextWidget->Anchor.CenterIn(Window->GetRootWidget());
  TextWidget->Text=[TextWidget]()->CString{
    auto Postion=SMouseButtonEvent::GetMosuePositionOnScreen();
    return U"鼠标位置："+CString(Postion.X)+U","+CString(Postion.Y);
  };
  TextWidget->Color=SColor::Green;

  Window->Show();

}

void TestMessageBox()
{
    WH::ShowMessageBox(U"测试",U"测试消息");
}

void TestRectangleWidget()
{
  //create a window and add a rectangle widget to it
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto Background=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Background->Anchor.Fill(Window->GetRootWidget());
  Background->FillColor=SColor::FromHexRGB(0x222222);

  auto Rectangle=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Rectangle->Width=100;
  Rectangle->Height=100;
  Rectangle->FillColor=SColor::Red;
  Rectangle->BorderColor=SColor::Green;
  Rectangle->BorderSize=5;
  Rectangle->Radius=20;

  auto RectangleNoFill=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  RectangleNoFill->X=200;
  RectangleNoFill->Width=100;
  RectangleNoFill->Height=100;
  RectangleNoFill->Fill=false;
  RectangleNoFill->BorderColor=SColor::Green;
  RectangleNoFill->BorderSize=5;
  RectangleNoFill->Radius=20;

  auto RectangleNoBorder=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  RectangleNoBorder->X=400;
  RectangleNoBorder->Width=100;
  RectangleNoBorder->Height=100;
  RectangleNoBorder->FillColor=SColor::Red;
  RectangleNoBorder->BorderSize=0;
  RectangleNoBorder->Radius=20;

  auto RectangleThinBorder=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  RectangleThinBorder->X=600;
  RectangleThinBorder->Y=100;
  RectangleThinBorder->Width=100;
  RectangleThinBorder->Height=100;
  RectangleThinBorder->FillColor=SColor::Red;
  RectangleThinBorder->BorderSize=1;
  RectangleThinBorder->BorderColor=SColor::Green;
  RectangleThinBorder->Radius=2;

  Window->Show();
}

void TestHorizontalPositioner()
{
  //create a window and add a rectangle widget to it
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto Background=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Background->Anchor.Fill(Window->GetRootWidget());
  Background->FillColor=SColor::FromHexRGB(0x222222);

  auto PositionerBackground=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  PositionerBackground->Fill=false;
  PositionerBackground->BorderColor=SColor::Green;
  PositionerBackground->BorderSize=1;

  static float PositionerWidth=600;
  PositionerBackground->Width=[]()->float{return PositionerWidth;};
  PositionerBackground->Height=100;

  auto HorizontalLayout=NewWidget<RHorizontalPositionerWidget>(PositionerBackground);
  HorizontalLayout->Anchor.Fill(PositionerBackground);
  HorizontalLayout->Spacing=10;
  HorizontalLayout->HideMethod=EHorizontalPositionerHideMethod::NevenHide;
  HorizontalLayout->Align=EHorizontalPositionerAlign::Right;

  auto Red=NewWidget<RRectangleWidget>(HorizontalLayout);
  Red->Width=200;
  Red->Height=50;
  Red->Y=10;
  Red->FillColor=SColor::Red;

  auto Green=NewWidget<RRectangleWidget>(HorizontalLayout);
  Green->Width=200;
  Green->Height=50;
  Green->Y=10;
  Green->FillColor=SColor::Green;

  auto Blue=NewWidget<RRectangleWidget>(HorizontalLayout);
  Blue->Width=200;
  Blue->Height=50;
  Blue->Y=10;
  Blue->FillColor=SColor::Blue;

  //增加两个按钮，一个增加宽度，一个减少宽度
  auto AddButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  AddButton->X=100;
  AddButton->Y=200;
  AddButton->Width=100;
  AddButton->Height=50;
  AddButton->Text=U"增加宽度";
  AddButton->OnClicked.BindLambda([PositionerBackground](
    const SMouseButtonEvent &InEvent)->bool{
    PositionerWidth+=10;
    return true;
  });

  auto SubButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  SubButton->X=100;
  SubButton->Y=300;
  SubButton->Width=100;
  SubButton->Height=50;
  SubButton->Text=U"减少宽度";
  SubButton->OnClicked.BindLambda([PositionerBackground](
    const SMouseButtonEvent &InEvent)->bool{
    PositionerWidth-=10;
    return true;
  });

  Window->Show();
}

void TestAnimation()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  
  //create Rectangle widget
  auto Rectangle=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Rectangle->Width=100;
  Rectangle->Height=100;

  Rectangle->Y=
    SAnimatedAttributeCreator::CreateFloatAttribute(
      0.f
      ,TWidgetAttribute<float>(500.f)
      ,TWidgetAttribute<float>(10.0f)
  );
  Rectangle->FillColor=SColor::Red;

  Window->Show();

}

void TestTextWidget()
{
  //create a window and add a text widget to it
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto WindowBackground=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  WindowBackground->Anchor.Fill(Window->GetRootWidget());
  WindowBackground->FillColor=SColor::FromHexRGB(0x111111);

  auto TextBackground=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  TextBackground->FillColor=SColor::Yellow;

  auto TextWidget=NewWidget<RTextWidget>(Window->GetRootWidget());
  TextWidget->Width=400;
  TextWidget->Y=20;
  TextWidget->Height=500;
  TextWidget->Text=U"啊！大海，你全是水";
  TextWidget->Color=SColor::Green;
  TextWidget->VerticalAlignment=ETextVerticalAlignment::Center;

  TextBackground->Anchor.VerticalCenterReference=TextWidget;
  TextBackground->Height=1;
  TextBackground->Anchor.HorizontalFill(TextWidget);

  Window->Show();  

}

//测试文本渲染效率
void TestTextRenderSpeed()
{
  //窗口左侧显示文本，右侧显示帧率
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));
  Window->Show();

  auto Background=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Background->Anchor.Fill(Window->GetRootWidget());
  Background->FillColor=SColor::FromHexRGB(0x222222);

  //帧率
  auto FrameRateText=NewWidget<RTextWidget>(Window->GetRootWidget());
  FrameRateText->X=400;
  FrameRateText->Y=20;
  FrameRateText->Height=100;
  FrameRateText->Width=400;

  //帧率每0.5秒更新一次
  static auto LastUpdateTime=std::chrono::steady_clock::now();
  static CString LastFrameRateText=U"帧率："+CString(RApplication::GetApplication()->GetLogicFPS());
  FrameRateText->Text=[FrameRateText]()->CString{

      auto Now=std::chrono::steady_clock::now();
      if(std::chrono::duration_cast<std::chrono::milliseconds>(Now-LastUpdateTime).count()>500)
      {
        LastUpdateTime=Now;
        LastFrameRateText=U"帧率："+CString(RApplication::GetApplication()->GetLogicFPS());
      }
      return LastFrameRateText;
  };
  FrameRateText->Color=SColor::Green;

  //在右侧放个按钮，点击后增加一个文本
  auto AddTextButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  AddTextButton->X=400;
  AddTextButton->Y=200;
  AddTextButton->Width=100;
  AddTextButton->Height=50;
  AddTextButton->Text=U"增加文本";
  AddTextButton->TextStyle.Color=SColor::Green;
  static float TextY=20;
  AddTextButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    auto TextWidget=NewWidget<RTextWidget>(Window->GetRootWidget());
    TextWidget->Width=400;
    TextWidget->Y=TextY;
    TextY+=2;
    TextWidget->Height=20;
    TextWidget->Text=U"啊！大海，你全是水";
    TextWidget->Color=SColor::Green;
    TextWidget->VerticalAlignment=ETextVerticalAlignment::Center;
    return true;
  });


}

void TestMultilineTextWidget()
{
  //create a window and add a text widget to it
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto TextWidget=NewWidget<RTextWidget>(Window->GetRootWidget());
  TextWidget->Width=400;
  TextWidget->Y=20;
  TextWidget->Height=500;
  TextWidget->Text=U"啊\n实打\n实打算DGDSFGHDFGHFFDEWDWWDSFWEDF阿斯顿发射点发射点";
  TextWidget->Wrap=ETextWrapMethod::WrapByWidthAndAtLineEnd;
  TextWidget->Color=SColor::Green;

  Window->Show();

}

void TestEditText()
{
  //create a window and add a text widget to it
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto Background=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Background->Anchor.Fill(Window->GetRootWidget());
  Background->FillColor=SColor::FromHexRGB(0x222222);


  auto TextWidget=NewWidget<REditableTextWidget>(Window->GetRootWidget());
  TextWidget->X=20;
  TextWidget->Width=300;
  TextWidget->Y=20;
  TextWidget->Height=100;
  TextWidget->Text=U"第一行啊撒大声地\n第二行啊撒大声地\n第三行啊撒大声地\n第四行啊撒大声地";


  Window->Show();


}

// void TestMultilineEditText()
// {
//   //create a window and add a text widget to it
//   auto Window=NewObject<RWindow>();
//   Window->SetWindowSize(SVec2(800,600));
//   Window->SetWindowPosition(SVec2(100,100));

//   auto Background=NewWidget<RRectangleWidget>(Window->GetRootWidget());
//   Background->Anchor.Fill(Window->GetRootWidget());
//   Background->FillColor=SColor::FromHexRGB(0x222222);
  
//   auto TextWidget=NewWidget<RMultiLineEditableTextWidget>(Window->GetRootWidget());
//   TextWidget->Width=800;
//   TextWidget->X=30;
//   TextWidget->Y=30;
//   TextWidget->Height=600;
//   TextWidget->Text=U"saadfsdfsdfsadfasfg\ndsfsdfsdfasdfsd";
//   TextWidget->Wrap=ETextWrapMethod::WrapByWidthAndAtLineEnd;

//   Window->Show();
// }

void TestDockLayout()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  //register several dock widget
  CString Group=U"WidgetTester";
  auto DockWidgetSubsystem=RDockWidgetSubsystem::Get();
  DockWidgetSubsystem->RegisterDockWidget(
    Group
    ,U"Red"
    ,U"Red"
    ,[](RWidget *Parent)->RWidgetPtr
  {
      auto Widget=NewWidget<RRectangleWidget>(Parent);
      Widget->FillColor=SColor::Red;
      return Widget;
  });

  DockWidgetSubsystem->RegisterDockWidget(
    Group,U"Green",U"Green",[](RWidget *Parent)->RWidgetPtr
  {
      auto Widget=NewWidget<RRectangleWidget>(Parent);
      Widget->FillColor=SColor::Green;
      return Widget;
  });

  DockWidgetSubsystem->RegisterDockWidget(
    Group,U"Blue",U"Blue",[](RWidget *Parent)->RWidgetPtr
  {
      auto Widget=NewWidget<RRectangleWidget>(Parent);
      Widget->FillColor=SColor::Blue;
      return Widget;
  });

  DockWidgetSubsystem->RegisterDockWidget(
    Group
    ,U"Yellow"
    ,U"Yellow"
    ,[](RWidget *Parent)->RWidgetPtr
  {
      auto Widget=NewWidget<RRectangleWidget>(Parent);
      Widget->FillColor=SColor::Yellow;
      return Widget;
  });

  DockWidgetSubsystem->RegisterDockWidget(
    Group,U"Black",
    U"Black",[](RWidget *Parent)->RWidgetPtr
  {
      auto Widget=NewWidget<RRectangleWidget>(Parent);
      Widget->FillColor=SColor::Black;
      return Widget;
  });




  auto DockLayout=NewWidget<RDockLayout>(Window->GetRootWidget());
  DockLayout->Anchor.Fill(Window->GetRootWidget());
  DockLayout->SetGroupName(Group);
  DockLayout->SetDirection(EDockLayoutDirection::Horizontal);
  DockLayout->DockWidget(U"Red");


  auto DockLayout2=NewWidget<RDockLayout>(DockLayout);
  DockLayout2->SetDirection(EDockLayoutDirection::Vertical);
  DockLayout2->SetGroupName(Group);
  DockLayout2->DockWidget(U"Blue");

  DockLayout->DockLayout(DockLayout2);

  auto DockLayout3=NewWidget<RDockLayout>(DockLayout);
  DockLayout3->SetDirection(EDockLayoutDirection::Stacked);
    DockLayout3->SetGroupName(Group);
  DockLayout2->DockLayout(DockLayout3);


    DockLayout3->DockWidget(U"Green");
    DockLayout3->DockWidget(U"Yellow");

  Window->Show();  

}

void TestContextMenu()
{
    auto Window=NewObject<RWindow>();
    Window->SetWindowSize(SVec2(800,600));
    Window->SetWindowPosition(SVec2(100,100));

    //create a background widget
    auto Background=NewWidget<RRectangleWidget>(Window->GetRootWidget());
    Background->Anchor.Fill(Window->GetRootWidget());


    auto MouseWidget=NewWidget<RMouseWidget>(Window->GetRootWidget());
    MouseWidget->Anchor.Fill(Window->GetRootWidget());

    TVector<RContextMenuWindow::SContextMenuItem> MenuItems;
    auto& FirstItem=MenuItems.Emplace();
    FirstItem.Text=U"First Item";
    auto& SecondItem=FirstItem.SubMenus.Emplace();
    SecondItem.Text=U"Second Item";
    auto& SecondInSecondList=FirstItem.SubMenus.Emplace();
    SecondInSecondList.Text=U"Second In Second List";

    auto& SecondInFirstList=MenuItems.Emplace();
    SecondInFirstList.Text=U"Second In First List";

    MouseWidget->OnClicked.BindLambda([Window,MenuItems](const SMouseButtonEvent &InEvent)->bool{
      //create a context menu
      auto ContextWindow=RContextMenuWindow::CreateContextMenuAtMouse(Window,MenuItems);
      ContextWindow->Show();
      return true;
    });

    Window->Show();
}

void TestCanvasWidget()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto CanvasWidget=NewWidget<RCanvasWidget>(Window->GetRootWidget());
  CanvasWidget->Width=400;
  CanvasWidget->Height=400;
  CanvasWidget->X=100;
  CanvasWidget->Y=100;
  CanvasWidget->AddLine(SVec2(0,0),SVec2(50,50),6,SColor::Red);
  CanvasWidget->AddLine(SVec2(0,100),SVec2(100,0),20,SColor::Blue);

  CanvasWidget->AddTriangle(SVec2(0,0),SVec2(100,0),SVec2(100,100),SColor::Green);

  CanvasWidget->AddImage(SVec2(50,50),SVec2(50,50),REngineDefaultPackage::Get()->GetEngineIcon());

  CanvasWidget->AddText(SVec2(50,50),U"我是\n一个程序员",SColor::Yellow,20);

  CanvasWidget->AddColorfulText(
    SVec2(100,100),
    U"我是一个程序员,\n代码本领强，\n我要把那坨坨屎，\n磊成一座山\n",
    {{0,SColor::Red},{19,SColor::Green},{22,SColor::Blue}},
    20);

  CanvasWidget->AddRect(SRect(SVec2(0,0),SVec2(100,100)),SColor::Red);  

  CanvasWidget->AddCircle(SVec2(100,100),50,SColor::Yellow);

  CanvasWidget->AddTextWithAlignment(
    SRect(SVec2(0,0),SVec2(100,100))
    ,U"我是一个程序员"
    ,SColor::Green
    ,20
    );

  Window->Show();


}


void TestScaleWidget()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(100,100));
  Window->SetWindowPosition(SVec2(100,100));

  auto ImageWidget= NewWidget<RImageWidget>(Window->GetRootWidget());
  ImageWidget->Scale=SVec2(3,3);
  ImageWidget->Image=REngineDefaultPackage::Get()->GetEngineIcon();

  
  Window->Show();
}

void TestScaledImage()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(1000,1000));
  Window->MoveToScreenCenter();

  auto ImageWidget= NewWidget<RImageWidget>(Window->GetRootWidget());
  //ImageWidget->Scale=SVec2(0.1,0.1);

  RTexture2D::STexture2DCreateInfo CreateInfo;
  TVector<uint8_t> PNGFileData={
    #include "Icons/Skybox/Front.png.h"
  };
  ImageWidget->Image=RTexture2D::CreateFromPNGFileData(std::move(PNGFileData));

  ImageWidget->X=50;
  ImageWidget->Y=50;
  ImageWidget->Width=900;
  ImageWidget->Height=900;
  ImageWidget->ScaleMethod=EImageWidgetScaleMethod::Custom;
  ImageWidget->CustomLeftTopUV=SVec2(0.5,0.5);
  ImageWidget->CustomRightBottomUV=SVec2(10,10);

  Window->Show();
}

void TestCollapsibleWidget()
{
    auto Window=NewObject<RWindow>();
    Window->SetWindowSize(SVec2(800,600));
    Window->SetWindowPosition(SVec2(100,100));

    auto CollapsibleWidget=NewWidget<RCollapsibleWidget>(Window->GetRootWidget());
    CollapsibleWidget->Width=100;
    auto Title=CollapsibleWidget->GetTitle();
    Title->Height=20;
    auto TitleBackground=NewWidget<RRectangleWidget>(Title);
    TitleBackground->Anchor.Fill(Title);
    TitleBackground->FillColor=SColor::Red;

    auto Content=CollapsibleWidget->GetContent();
    Content->Height=100;
    auto ContentBackground=NewWidget<RRectangleWidget>(Content);
    ContentBackground->Anchor.Fill(Content);
    ContentBackground->FillColor=SColor::Blue;

    Window->Show();
}

void TestFileBrowser()
{
    auto Window=NewObject<RWindow>();
    Window->SetWindowSize(SVec2(800,600));
    Window->MoveToScreenCenter();
    Window->SetWindowTitle(U"保存");

    auto FilerBrowser= NewWidget<RFileBrowserWidget>(Window->GetRootWidget());
    FilerBrowser->Anchor.Fill(Window->GetRootWidget());
    FilerBrowser->ShowContent(SPaths::GetWorkingDirectory());

    Window->Show();  

}

void TestOpenFileDialog()
{
  auto Paths=WH::CreateOpenFileDialog(
    U"打开文件"
    ,SPaths::GetWorkingDirectory()
    ,{U"图片(*.png)",U"*.jpg",U"*.bmp"}
    ,true
    );

  if(Paths.Empty())
  {
    WH::PrintLine(CString(U"用户取消了操作"));
  }
  else
  {
    for(auto& Path:Paths)
    {
      WH::PrintLine(Path.ToString());
    }
  }

}

void TestSaveFileDialog()
{
  auto Path=WH::CreateSaveFileDialog(
    U"保存文件"
    ,SPaths::GetWorkingDirectory()
    ,U"图片(*.png)"
    );

  if(Path.HasValue())
  {
    WH::PrintLine(Path.GetValue().ToString());
  }
  else
  {
    WH::PrintLine(CString(U"用户取消了操作"));
  }
}

void TestSelectFolderDialog()
{
  auto Path=WH::CreateFolderDialog(
    U"选择文件夹"
    ,SPaths::GetWorkingDirectory()
    );

  if(Path.HasValue())
  {
    WH::PrintLine(Path.GetValue().ToString());
  }
  else
  {
    WH::PrintLine(CString(U"用户取消了操作"));
  }
}

TSharedObjectPtr<RScene> CreatePreviewScene()
{
    RScenePtr Scene=NewObject<RScene>();
    {
        auto Light=Scene->NewNode<RSceneNode>(); 
        Light->SetNodeName(U"DirectionalLight");
        Light->SetWorldPosition(SVec3(0,0,0)); //any where is ok
        Light->SetWorldRotation(SQuat::FromEuler(SVec3(CMathBase::DegreeToRadian(-45.f),0,0)));
        {
            auto LightComponent=Light->CreateAndAddComponent<RDirectionalLightComponent>();
            auto TickComponent=Light->CreateAndAddComponent<RTickComponent>();
            TickComponent->TickFunction.BindLambda([Light](float DeltaTime){
                static float Rz=0;
                Rz+=1;
                Light->SetWorldRotation(SQuat::FromEuler(SVec3(CMathBase::DegreeToRadian(-45.f),0,Rz)));
            });
        }

        auto GreyFloor=Scene->NewNode<RSceneNode>(); 
        GreyFloor->SetNodeName(U"GreyFloor");
        GreyFloor->SetWorldPosition(SVec3(0,0,-1));
        GreyFloor->SetScale(SVec3(10,10,1));
        {
            auto MeshComponent=GreyFloor->CreateAndAddComponent<RStaticMeshComponent>();
            MeshComponent->SetStaticMesh(REngineDefaultPackage::Get()->GetCubeMesh());
            MeshComponent->SetMaterials({REngineDefaultPackage::Get()->GetDefaultMaterial()});
        }

        auto Cube=Scene->NewNode<RSceneNode>(); 
        Cube->SetWorldPosition(SVec3(0,0,0));
        Cube->SetWorldRotation(SQuat::FromEuler(SVec3(0,0,0)));
        auto PreviewMeshComponent=Cube->CreateAndAddComponent<RStaticMeshComponent>();
        {
            PreviewMeshComponent->SetStaticMesh(REngineDefaultPackage::Get()->GetCubeMesh());
            PreviewMeshComponent->SetMaterials({REngineDefaultPackage::Get()->GetDefaultMaterial()});
        }

        auto Camera=Scene->NewNode<RSceneNode>(); 
        Camera->SetNodeName(U"Camera");
        auto CameraComponent=Camera->CreateAndAddComponent<RCameraComponent>();
        Camera->SetWorldPosition(SVec3(0,-3,2));
        Camera->SetWorldRotation(SQuat::FromEuler(SVec3(CMathBase::DegreeToRadian(-30.f),0,0))); 

        Scene->BeginPlay();
    }

    return Scene;
}

void TestViewport()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto Viewport=NewWidget<RViewportWidget>(Window->GetRootWidget());
  Viewport->Anchor.Fill(Window->GetRootWidget());

  Viewport->SetScene(CreatePreviewScene());

  Window->Show();


}

void TestPixelObject()
{
  RApplication::GetApplication()->EnablePrintFPS();

  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto Viewport=NewWidget<RViewportWidget>(Window->GetRootWidget());
  Viewport->Anchor.Fill(Window->GetRootWidget());

  Viewport->SetScene(CreatePreviewScene());
  
  Viewport->AxisVisible=true;
  Viewport->AxisOrigin=SVec3(0,0,0);
  
  auto PixelObjectMap=NewObject<RPixelObjectMap>();
  Viewport->PixelObjectMap=PixelObjectMap;

  auto ViewportMouse=NewWidget<RMouseWidget>(Viewport);
  ViewportMouse->Anchor.Fill(Viewport);

  ViewportMouse->OnClicked.BindLambda([PixelObjectMap,ViewportMouse](const SMouseButtonEvent &InEvent)->bool{
    auto MousePosition=ViewportMouse->GetMousePositionInWidget();
    auto PixelObject=PixelObjectMap->QueryPixelObject(MousePosition);
    if(PixelObject)
    {
      if(PixelObject->ObjectType==EPixelObjectType::Axis)
      {
        std::shared_ptr<CAxisPixelObject> AxisObject=std::static_pointer_cast<CAxisPixelObject>(PixelObject);
        switch (AxisObject->AxisType)
        {
        case EAxis::X:
          WH::PrintLine(CString(U"点击到了X轴"));
          break;
        case EAxis::Y:
          WH::PrintLine(CString(U"点击到了Y轴"));
          break;
        case EAxis::Z:
          WH::PrintLine(CString(U"点击到了Z轴"));
          break;
        }
        return true;
      }
      
    }

    WH::PrintLine(CString(U"点击到了空白处"));
    
    return true;
  });

  Window->Show();  
}

void TestButton()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto Button=NewWidget<RButtonWidget>(Window->GetRootWidget());
  Button->X=100;
  Button->Y=100;
  Button->Width=100;
  Button->Height=100;

  Button->Text=U"按钮";
  Button->TextStyle.Color=SColor::Green;

  // Button->Icon.Texture=REngineDefaultPackage::Get()->GetEngineIcon();
  // Button->Icon.Width=50;
  // Button->Icon.Height=50;

  auto WeakButton=TWeakObjectPtr<RButtonWidget>(Button);
  Button->BackgroundStyle.FillColor=([WeakButton]()->SColor{
    if(WeakButton->IsHovered())
    {
      return SColor::Red;
    }
    else
    {
      return SColor::Blue;
    }
  });

  Button->OnClicked.BindLambda([WeakButton](const SMouseButtonEvent &InEvent)->bool{
      WeakButton->Text=U"点击了";
      return true;
  });

  Window->Show();
}

//测试窗口形态变化 
void TestWindow()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));
  Window->SetWindowTitle(U"窗口测试");
  //Window->ShowSystemBorder();
  Window->Show();
  Window->GetRootWidget()->Fill=false;

  

  //只填充窗口的一部分,以测试窗口没有填充的部分样式
  auto Background=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Background->Anchor.HorizontalFill(Window->GetRootWidget());
  Background->Anchor.BottomReference=Window->GetRootWidget();
  Background->Height=100;

  auto FullScreenButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  FullScreenButton->Width=50;
  FullScreenButton->Height=50;
  FullScreenButton->Text=U"全屏";
  FullScreenButton->TextStyle.Color=SColor::Green;
  FullScreenButton->BackgroundStyle.FillColor=SColor::Blue;

  FullScreenButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->FullScreen();
    return true;
  });

  auto RestoreButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  RestoreButton->X=60;
  RestoreButton->Width=50;
  RestoreButton->Height=50;
  RestoreButton->Text=U"还原";
  RestoreButton->TextStyle.Color=SColor::Green;
  RestoreButton->BackgroundStyle.FillColor=SColor::Blue;

  RestoreButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->Restore();
    return true;
  });

  auto MinimizeButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  MinimizeButton->X=120;
  MinimizeButton->Width=50;
  MinimizeButton->Height=50;
  MinimizeButton->Text=U"最小化";
  MinimizeButton->TextStyle.Color=SColor::Green;
  MinimizeButton->BackgroundStyle.FillColor=SColor::Blue;

  MinimizeButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->Minimize();
    return true;
  });

  auto MaximizeButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  MaximizeButton->X=180;
  MaximizeButton->Width=50;
  MaximizeButton->Height=50;
  MaximizeButton->Text=U"最大化";
  MaximizeButton->TextStyle.Color=SColor::Green;
  MaximizeButton->BackgroundStyle.FillColor=SColor::Blue;

  MaximizeButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->Maximize();
    return true;
  });

  auto ResetSizeButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  ResetSizeButton->X=240;
  ResetSizeButton->Width=50;
  ResetSizeButton->Height=50;
  ResetSizeButton->Text=U"重置大小";
  ResetSizeButton->TextStyle.Color=SColor::Green;
  ResetSizeButton->BackgroundStyle.FillColor=SColor::Blue;

  ResetSizeButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->SetWindowSize(SVec2(800,600));
    return true;
  });

  auto ToggleBorderButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  ToggleBorderButton->X=300;
  ToggleBorderButton->Width=50;
  ToggleBorderButton->Height=50;
  ToggleBorderButton->Text=U"切换边框";
  ToggleBorderButton->TextStyle.Color=SColor::Green;
  ToggleBorderButton->BackgroundStyle.FillColor=SColor::Blue;

  ToggleBorderButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    if(!Window->IsBorderVisible())
    {
      Window->ShowSystemBorder();
    }
    else
    {
      Window->HideSystemBorder();
    } 
    Window->Hide();
    Window->Show();
    return true;
  });


}

void TestWindowButtons()
{
  auto Window=NewObject<RWindow>();
  Window->HideSystemBorder();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));
  Window->SetWindowTitle(U"最大化测试");

  auto Background=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Background->Anchor.Fill(Window->GetRootWidget());
  Background->FillColor=SColor::FromHexRGB(0x222222);

  auto Button=NewWidget<RButtonWidget>(Window->GetRootWidget());
  Button->X=100;
  Button->Y=100;
  Button->Width=100;
  Button->Height=100;

  Button->Text=U"最大化";
  Button->TextStyle.Color=SColor::Green;
  Button->BackgroundStyle.FillColor=SColor::Blue;

  Button->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->Maximize();
    return true;
  });

  //create a button to restore window
  auto RestoreButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  RestoreButton->X=210;
  RestoreButton->Y=100;
  RestoreButton->Width=100;
  RestoreButton->Height=100;

  RestoreButton->Text=U"还原";
  RestoreButton->TextStyle.Color=SColor::Green;
  RestoreButton->BackgroundStyle.FillColor=SColor::Blue;

  RestoreButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->Restore();
    return true;
  });

  //move to Left
  auto MoveToLeftButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  MoveToLeftButton->X=320;
  MoveToLeftButton->Y=100;
  MoveToLeftButton->Width=100;
  MoveToLeftButton->Height=100;

  MoveToLeftButton->Text=U"左";
  MoveToLeftButton->TextStyle.Color=SColor::Green;
  MoveToLeftButton->BackgroundStyle.FillColor=SColor::Blue;

  MoveToLeftButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->SetWindowPosition(Window->GetWindowPosition()-SVec2(10,0));
    return true;
  });

  //move to Right
  auto MoveToRightButton=NewWidget<RButtonWidget>(Window->GetRootWidget());
  MoveToRightButton->X=430;
  MoveToRightButton->Y=100;
  MoveToRightButton->Width=100;
  MoveToRightButton->Height=100;

  MoveToRightButton->Text=U"右";
  MoveToRightButton->TextStyle.Color=SColor::Green; 
  MoveToRightButton->BackgroundStyle.FillColor=SColor::Blue;

  MoveToRightButton->OnClicked.BindLambda([Window](const SMouseButtonEvent &InEvent)->bool{
    Window->SetWindowPosition(Window->GetWindowPosition()+SVec2(10,0));
    return true;
  });


  Window->Show();
}

//测试输入法位置
//微软输入法、搜狗测试成功
//讯飞输入法测试失败，当屏幕缩放比例不为100%时，输入法位置不正确
void TestIMEPosition()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(300,200));

  SIntPoint Position=SIntPoint(210,440);
  auto Size=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Size->Width=Position.X;
  Size->Height=Position.Y;
  Size->FillColor=SColor::Red;

  auto MouseWidget=NewWidget<RMouseWidget>(Window->GetRootWidget());
  MouseWidget->Anchor.Fill(Window->GetRootWidget());
  MouseWidget->OnClicked.BindLambda([Window,Size,Position](const SMouseButtonEvent &InEvent)->bool{
    IPlatformInterface::GetPlatformInterface()->StartTextInput(
      Window->GetWindowID()
      ,Window->ContentSpaceToWindowSpace(Position)
    );
    return true;
  });

  Window->Show();
}

void TestAnchor()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->SetWindowPosition(SVec2(100,100));

  auto Widget=NewWidget<RRectangleWidget>(Window->GetRootWidget());
  Widget->FillColor=SColor::Red;
  Widget->X=150;
  Widget->Anchor.HorizontalCenterReference=Window->GetRootWidget();

  Widget->Y=150;
  Widget->Anchor.BottomReference=Window->GetRootWidget();


  Window->Show();
}


void TestMultiViewport()
{
  auto Window=NewObject<RWindow>();
  Window->SetWindowSize(SVec2(800,600));
  Window->MoveToScreenCenter();

  auto Scene=CreatePreviewScene();

  auto LeftViewport=NewWidget<RViewportWidget>(Window->GetRootWidget());
  LeftViewport->X=0;
  LeftViewport->Y=0;
  LeftViewport->Width=400;
  LeftViewport->Height=600;
  LeftViewport->SetScene(Scene);
  LeftViewport->ViewportRotation=SQuat::FromEuler(SVec3(0.2,0,0));
  LeftViewport->bForceUseDefaultParameters=true;

  auto RightViewport=NewWidget<RViewportWidget>(Window->GetRootWidget());
  RightViewport->X=400;
  RightViewport->Y=0;
  RightViewport->Width=400;
  RightViewport->Height=600;
  RightViewport->SetScene(Scene);
  RightViewport->bForceUseDefaultParameters=true;

  Window->Show();

}

int main(int argc, char* argv[])
{
  auto App=NewObject<RApplication>();

  SApplicationArgument Argument;
  Argument.ExecutablePath=argv[0];
  Argument.FallBackFont=Argument.ExecutablePath.Parent()/U"Content"/U"WidgetTester"/U"Fonts"/U"SourceHanSansHWSC-Bold.otf";
  Argument.DefaultFont=Argument.FallBackFont;
  App->Initialize(Argument);
  //App->EnablePrintFPS();

  TestAnchor();

  return App->Run();
}